package com.atguigu.tingshu.account.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.account.mapper.UserAccountMapper;
import com.atguigu.tingshu.account.service.MqOpsService;
import com.atguigu.tingshu.account.service.UserAccountService;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.model.account.UserAccount;
import com.atguigu.tingshu.vo.account.AccountLockResultVo;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * @Author：yyj
 * @Package：com.atguigu.tingshu.account.service.impl
 * @Project：tingshu_parent240829
 * @name：MqOpsServiceImpl
 * @Date：2025/1/14 2:43
 * @Filename：MqOpsServiceImpl
 */
@Service
public class MqOpsServiceImpl implements MqOpsService {
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserAccountService userAccountService;

    @Override
    public void userAccountInit(String userId) {

        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(Long.parseLong(userId));
        userAccountMapper.insert(userAccount);
    }

    @Override
    public void unLock(String orderNo) {
        //锁定余额- 可用余额+
        //1,从redis锁定查询记录
        String userAccountResultKey = "user:account:data" + orderNo;
        String msgRepeatLockKey = "msg:repeat:" + orderNo;
        String lockStr = redisTemplate.opsForValue().get(userAccountResultKey);
        if (StringUtils.isEmpty(lockStr)) {// 解决幂等性
            return;
        }
        // 2.获取数据
        AccountLockResultVo accountLockResultVo = JSONObject.parseObject(lockStr, AccountLockResultVo.class);
        Long userId = accountLockResultVo.getUserId();
        BigDecimal amount = accountLockResultVo.getAmount();
        String content = accountLockResultVo.getContent();
        // 3.解锁
        try {
            Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(msgRepeatLockKey, "1");
            if (aBoolean) {
                userAccountMapper.unLock(userId, amount);
                // 4.记录流水
                userAccountService.log(userId, "解锁" + content, "1203", amount, orderNo);
                // 5.将锁定记录从Redis中删除掉
                redisTemplate.delete(userAccountResultKey);
            }
        } catch (Exception e) {
            throw new GuiguException(201, "业务执行失败");
        } finally {
            redisTemplate.delete(msgRepeatLockKey);
        }

    }

    @Override
    public void minus(String orderNo) {
        //锁定余额- 可用余额+
        //1,从redis锁定查询记录
        String userAccountResultKey = "user:account:data" + orderNo;
        String msgRepeatLockKey = "msg:repeat:" + orderNo;
        String lockStr = redisTemplate.opsForValue().get(userAccountResultKey);
        if (StringUtils.isEmpty(lockStr)) {// 解决幂等性
            return;
        }
        // 2.获取数据
        AccountLockResultVo accountLockResultVo = JSONObject.parseObject(lockStr, AccountLockResultVo.class);
        Long userId = accountLockResultVo.getUserId();
        BigDecimal amount = accountLockResultVo.getAmount();
        String content = accountLockResultVo.getContent();
        // 3.解锁
        try {
            Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(msgRepeatLockKey, "1");
            if (aBoolean) {
                userAccountMapper.minus(userId, amount);
                // 4.记录流水
                userAccountService.log(userId, "消费" + content, "1204", amount, orderNo);
                // 5.将锁定记录从Redis中删除掉
                redisTemplate.delete(userAccountResultKey);
            }
        } catch (Exception e) {
            throw new GuiguException(201, "业务执行失败");
        } finally {
            redisTemplate.delete(msgRepeatLockKey);
        }
    }
}
